﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Xejen.Database.Entities.Auditing
{
    /// <summary>
    /// 表示实体(默认主键类型是<see langword="long"/>)的创建信息
    /// </summary>
    /// <remarks>
    /// 包含创建时间，创建人，主键id
    /// </remarks>    
    [Serializable]
    public abstract class FullAuditedEntity : FullAuditedEntity<long>, IEntity
    {
        /// <inheritdoc cref="FullAuditedEntity"/>
        protected FullAuditedEntity() { }
    }

    /// <summary>
    /// 表示实体的创建信息
    /// </summary>
    /// <remarks>
    /// 包含创建时间，创建人主键id
    /// </remarks>
    /// <typeparam name="TPrimaryKey">实体的主键类型</typeparam>
    [Serializable]
    public abstract class FullAuditedEntity<TPrimaryKey> : Entity<TPrimaryKey>, ICreationAudited, IModificationAudited
        where TPrimaryKey : struct
    {
        /// <inheritdoc/>
        [Description("创建人的用户Id")]
        public virtual long? CreatorUserId { get; set; }

        /// <inheritdoc/>
        [Description("创建时间")]
        public virtual DateTime CreationTime { get; set; }

        /// <inheritdoc/>
        [Description("创建人的用户Id")]
        public virtual long? ModifierUserId { get; set; }

        /// <inheritdoc/>
        [Description("修改时间")]
        public virtual DateTime? ModificationTime { get; set; }

        /// <inheritdoc cref="FullAuditedEntity{TPrimaryKey}"/>
        protected FullAuditedEntity()
        {
            CreationTime = StandardTime.Now;
            ModificationTime = StandardTime.Now;
        }
    }

    /// <summary>
    /// 表示实体的创建信息
    /// </summary>
    /// <remarks>
    /// 包含创建时间，创建人主键id，创建人信息
    /// </remarks>
    /// <typeparam name="TPrimaryKey">实体的主键类型</typeparam>
    /// <typeparam name="TUser">用户表的类型</typeparam>
    [Serializable]
    public abstract class FullAuditedEntity<TPrimaryKey, TUser> : FullAuditedEntity<TPrimaryKey>, ICreationAudited<TUser>, IModificationAudited<TUser>
        where TPrimaryKey : struct
        where TUser : IEntity
    {
        /// <inheritdoc/>
        [ForeignKey("CreatorUserId")]
        public virtual TUser CreatorUser { get; set; }

        /// <inheritdoc/>
        [ForeignKey("ModifierUserId")]
        public virtual TUser ModifierUser { get; set; }

        /// <inheritdoc cref="FullAuditedEntity{TPrimaryKey, TUser}"/>
        protected FullAuditedEntity()
        {

        }
    }
}
